﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Agile.Engine.View;
using System.Collections;
using Agile.Engine;
using Agile.Engine.Data;
using System.Data;

namespace Fis.Win.Rules
{
    public class NewYearBookProvider : ClientViewProvider
    {


        string newBookPath { get; set; }
        DataContext newBookContext { get; set; }

        public NewYearBookProvider()
        {
            newBookPath = string.Format("{0}/newbook.sdf", ObjectContext.Environment.Config);
            newBookContext = Agile.Engine.Data.DataContext.SqlceContext(newBookPath);
        }

        public override Hashtable InitializeViewModel(Hashtable args)
        {
            var model = args ?? new Hashtable();
            return model;
        }

        public override bool ExecuteUpdate(Hashtable viewModel)
        {
            //新账套创建
            //1 复制tbook信息
            //2 复制基础信息
            //3 创建初始凭证

            //加载模板
            var cache = Agile.Engine.Utils.IOUtils.ReadStream("assembly://Agile.Engine.Config/Agile.Engine.Config.Schema/cache.sdf");
            Agile.Engine.Utils.IOUtils.WriteStream(cache, newBookPath);

            var xml = ObjectContext.GetResource("SqlResource");
            var tables = xml.GetString("new_year_book_copy");
            foreach (var tbl in tables.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
                CopyDataTable(tbl);

            #region == 新建信息 ==

            var bookInfo = DataContext.DefaultModel.QueryTable("TBOOK");

            var defaultRow = bookInfo.Rows[0];
            defaultRow["FBOOKSTARTIME"] = DateTime.Parse(Fis.Win.Utils.AppSession.Year + "-1-1").AddYears(1);
            defaultRow["FBOOKRANGE"] = 0;
            defaultRow["FBOOKINITIALIZED"] = 0;
            //写入
            var da = new DataAccess() { Context = newBookContext, TableName = "TBOOK" };
            da.Delete(Fis.Win.Utils.AppSession.BookID);
            da.AddNew(defaultRow);

            CopyInitialize();
            #endregion

            #region == 上传到服务器 ==

            var param = Fis.Win.Utils.AppSession.CreateServiceParamter(viewModel);
            param["newbook"] = Agile.Engine.Utils.ZipUtils.ZipBase64(Agile.Engine.Utils.IOUtils.ReadStream(newBookPath));
            param["action"] = "newyear";
            var exec = InvokeService(param);
            View.Message = ServiceProcess.Message;
            if (exec)
            {
                var sdf = string.Format("{0}/cache.sdf", ObjectContext.Environment.Config);
                System.IO.File.Delete(sdf);
                System.IO.File.Move(newBookPath, sdf);
                Fis.Win.Utils.AppSession.InitializeBookInfo();
            }
            #endregion

            return exec;
        }

        /// <summary>
        /// 创建初始余额信息
        /// </summary>
        void CopyInitialize()
        {
            //取科目余额
            var sql = ObjectContext.GetResource("SqlResource").GetString("last_rest");
            var rest = DataContext.DefaultModel.QueryTable(CommandType.Text, "TREST", sql);
            //生成余额凭证
            var billDetail = DataContext.DefaultModel.QueryTable("TBILLDETAIL", "1=2");
            var newBillID = Guid.NewGuid().ToString();
            //辅助核算余额
            var hsrest = DataContext.DefaultModel.QueryTable("TFZHSREST", "FRANGE=12");
            var hashcode = newBillID.GetHashCode();
            var sequnce = 0;
            var account = Fis.Win.Utils.CacheContext.LowerAccountCache();
            account.PrimaryKey = new DataColumn[] { account.Columns["SID"] };
            foreach (var d in rest.AsEnumerable())
            {
                var detailRow = billDetail.NewRow();
                detailRow["SID"] = string.Format("{0}-{1:0000#}", hashcode, ++sequnce);
                detailRow["FVCHID"] = newBillID;
                detailRow["FEXPLANATION"] = string.Format("{0}年初数", d["FNAME"]);
                detailRow["FACCOUNTCODE"] = d["FACCCODE"];

                #region == 金额 ==
                var debit = Fis.Win.Utils.ReportUtils.NullParse(d["FDEBITAMOUNTQM"]);
                var credit = Fis.Win.Utils.ReportUtils.NullParse(d["FCREDITAMOUNTQM"]);
                var debitC = Fis.Win.Utils.ReportUtils.NullParse(d["FCURRENCYDEBITQM"]);
                var creditC = Fis.Win.Utils.ReportUtils.NullParse(d["FCURRENCYCREDITQM"]);
                var debitQ = Fis.Win.Utils.ReportUtils.NullParse(d["FCURRENCYDEBITQM"]);
                var creditQ = Fis.Win.Utils.ReportUtils.NullParse(d["FCURRENCYCREDITQM"]);

                var jd = account.Rows.Find(d["FACCCODE"])["FJD"].Equals("1");

                if (jd)//借方
                {
                    detailRow["FDEBITAMOUNT"] = debit - credit;
                    detailRow["FCURRENCYDEBIT"] = debitC - creditC;
                    detailRow["FQUANTITYDEBIT"] = debitQ - creditQ;

                }
                else
                {
                    detailRow["FCREDITAMOUNT"] = credit - debit;
                    detailRow["FCURRENCYCREDIT"] = creditC - debitC;
                    detailRow["FQUANTITYCREDIT"] = creditQ - debitQ;
                }

                #endregion

                #region == 汇率 ==

                decimal rate = 0, price = 0;

                if (debit == 0 && creditC != 0)
                {
                    rate = credit / creditC;
                }
                else if (credit == 0 && debitC != 0)
                {
                    rate = debit / debitC;
                }

                detailRow["FRATE"] = rate;
                #endregion

                #region == 单价 ==
                if (debit == 0 && creditQ != 0)
                {
                    price = credit / creditQ;
                }
                else if (credit == 0 && debitQ != 0)
                {
                    price = debit / debitQ;
                }
                detailRow["FUNITPRICE"] = price;
                #endregion

                #region == 辅助核算 ==
                var hsx = hsrest.Select(string.Format("FACCCODE='{0}'", d["FACCCODE"]));
                if (hsx.Length > 0)
                {

                    StringBuilder builder = new StringBuilder();
                    foreach (var h in hsx)
                    {
                        builder.AppendFormat("{0}:{1},", h["FHSTYPE"], h["FHSID"]);
                    }
                    builder.Remove(builder.Length - 1, 1);
                    detailRow["FHSVALUE"] = builder.ToString();
                }
                if (debit != 0 && credit != 0)
                    billDetail.Rows.Add(detailRow);
                #endregion

            }

            #region == 凭证主表 ==

            var billMaster = DataContext.DefaultModel.QueryTable("TBILLMASTER", "1=2");
            var masterRow = billMaster.NewRow();
            masterRow["SID"] = newBillID;
            masterRow["FBILLTYPE"] = 0;
            masterRow["FNO"] = 1;
            masterRow["FATTACHMENT"] = 0;
            masterRow["FREMARK"] = string.Empty;
            masterRow["FENTERDATE"] = DateTime.Parse(Fis.Win.Utils.AppSession.Year + "-12-30");
            masterRow["FENTER"] = Fis.Win.Utils.AppSession.UserSID;
            masterRow["FCHECKED"] = Fis.Win.Utils.AppSession.UserSID;
            masterRow["FPOST"] = Fis.Win.Utils.AppSession.UserSID;
            masterRow["FSTATUS"] = 4;
            masterRow["FSORT"] = 0;
            masterRow["FSORTID"] = 0;
            masterRow["FSEQUENCE"] = 1;
            masterRow["FSYNC"] = 1;

            #endregion

            //写入初始凭证
            var mstda = new DataAccess() { TableName = "TBILLMASTER", Context = newBookContext };
            var dtlda = new DataAccess() { TableName = "TBILLDETAIL", Context = newBookContext };
            mstda.AddNew(masterRow);
            dtlda.AddNew(billDetail.Select());
        }

        /// <summary>
        /// 复制数据表
        /// </summary>
        /// <param name="name"></param>
        void CopyDataTable(string name)
        {
            newBookContext.DefaultModel.Delete(name, "1=1");
            var newda = new DataAccess { Context = newBookContext, TableName = name };
            newda.AddNew(this.DataContext.DefaultModel.QueryTable(name).Select());
        }
    }
}
